﻿using LoableTech;
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Threading;
using UpdateShare;

namespace ZipExtractorCore
{
    class Program
    {
        static void Main(string[] args)
        {
            FlagParser.Parse(args);
            var exeFile = FlagParser.StringFlag("exeFile", string.Empty, true);
            var exePath = FlagParser.StringFlag("exePath", string.Empty, true);
            var zipFile = FlagParser.StringFlag("zipFile", string.Empty, true);
            var serviceName = FlagParser.StringFlag("serviceName", string.Empty, true);

            if (string.IsNullOrWhiteSpace(exeFile) || string.IsNullOrWhiteSpace(exePath) || string.IsNullOrWhiteSpace(zipFile))
            {
                Console.WriteLine("Invalid Parameters");
                return;
            }
            else
            {
                Console.WriteLine($"exeFile:{exeFile}");
                Console.WriteLine($"exePath:{exePath}");
                Console.WriteLine($"zipFile:{zipFile}");
            }
            // make sure exe file to update is not running
            foreach (var proc in Process.GetProcesses())
            {
                try
                {
                    if (proc.MainModule.FileName.Equals(exeFile, StringComparison.OrdinalIgnoreCase))
                    {
                        Console.WriteLine("-- Waiting for exit " + exeFile + " --");
                        proc.WaitForExit();
                        Console.WriteLine("-- Application closed " + exeFile + " --");
                    }
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                }

            }
            Console.WriteLine("-- Waiting for process to close --");
            Thread.Sleep(1000);

            //停止服务
            if (!string.IsNullOrWhiteSpace(serviceName))
            {
                Console.WriteLine("-- Stopping Service --");
                CmdHelper.SystemCtlService(serviceName, "stop");
            }

            //解压
            using var zip = ZipStorer.Open(zipFile, FileAccess.Read);
            var dir = zip.Files.Values;
            //注意安装路径，如果压缩包包含目录，这里就取上一级目录
            string distinationPath = Directory.GetParent(exePath).FullName;
            Console.WriteLine($"-- Extracting File to {distinationPath}");
            foreach (var item in dir)
            {
                try
                {
                    //skip self
                    if (item.FilenameInZip.Contains("ZipExtractor", StringComparison.OrdinalIgnoreCase))
                        continue;
                    var extractFile = Path.Combine(distinationPath, item.FilenameInZip);//注意压缩包路径和解压路径
                    if (File.Exists(extractFile))
                    {
                        //Console.WriteLine("-- Deleting File " + extractFile);
                        File.Delete(extractFile);
                    }
                    //Console.WriteLine($"-- Extracting File: {extractFile}");
                    //解压
                    zip.ExtractFile(item, extractFile);
                    //Console.WriteLine("-- Done Extracting File " + extractFile);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message);
                    continue;
                }
            }
            zip.Close();


            //启动服务
            if (!string.IsNullOrWhiteSpace(serviceName))
            {
                //授权服务
                CmdHelper.PermissionX(serviceName);
                Console.WriteLine("-- Starting Service --");
                CmdHelper.SystemCtlService(serviceName, "start");
            }



            //独立发布，所以不用dotnet运行时
            string exeFileName = exeFile.Replace(".exe", "").Replace(".dll", "");
            //授权主程序 可执行权限
            CmdHelper.PermissionX(exeFileName);
            //启动桌面程序
            CmdHelper.StartExe(exeFileName);




            File.Delete(zipFile);
            Console.WriteLine("-- Update Done --");
            return;
        }


    }
}
